﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using QDJwt.Token;
using MyApp.DB;
using MyApp.Model;
using MySql.Data.MySqlClient;
using Dapper;
using System.Data;
using QDCommon.Controller;
using QDCommon.Time;
using System.Dynamic;
using Microsoft.AspNetCore.Authorization;
using log4net;

namespace MyApp.Controllers
{
    public class AccountController : BaseController
    {
        private readonly TokenGenerator _tokenGenerator;
        private readonly MysqlManager _db;
        private ILog _log;
        public AccountController(TokenGenerator tokenGenerator, MysqlManager db)
        {
            _log = LogManager.GetLogger(Startup.repository.Name, typeof(AccountController));
            _tokenGenerator = tokenGenerator;
            _db = db;
        }

        public async Task<IActionResult> Login([FromBody]LoginModel model)
        {
            if(ModelState.IsValid)
            {
                User userInfo = null;
                await _db.Query(async conn =>
                {
                    var lookup = new Dictionary<int, User>();
                    var users = await conn.QueryAsync<User, Role, User>("select_user_role_by_password", (user, role) =>
                    {
                        if (!lookup.TryGetValue(user.UserId, out User u))
                        {
                            lookup[user.UserId] = user;
                            u = user;
                        }
                        if (u.Roles == null)
                        {
                            u.Roles = new List<iRole>();
                        }
                        u.Roles.Add(role);
                        return u;
                    }, param: model, splitOn: "RoleId", commandType: CommandType.StoredProcedure);
                    userInfo = users.FirstOrDefault();
                });
                if(userInfo==null)
                {
                    _log.Info(model.UserName + "login failed");
                    return Error(QDCommon.Model.StateCode.UserNotExist, "user not exist or password error");
                }
                else{
                    string token = await _tokenGenerator.GenerateToken(userInfo, TimeStampHelper.TimeStamp());
                    dynamic result = new ExpandoObject();
                    result.Token = token;
                    result.UserInfo = userInfo;
                    _log.Info(model.UserName+"logined");
                    return Succed(result);
                }
               
            }
            else
            {
                _log.Info(model.UserName + "login failed");
                return Error(QDCommon.Model.StateCode.ParameterErro, "para error");
            }
        }
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult>UserInfo()
        {
            User userInfo = null;
            await _db.Query(async conn =>
            {
                var lookup = new Dictionary<int, User>();
                var users = await conn.QueryAsync<User, Role, User>("select_user_role", (user, role) =>
                {
                    if (!lookup.TryGetValue(user.UserId, out User u))
                    {
                        lookup[user.UserId] = user;
                        u = user;
                    }
                    if (u.Roles == null)
                    {
                        u.Roles = new List<iRole>();
                    }
                    u.Roles.Add(role);
                    return u;
                }, param: new{ UserName = UserName}, splitOn: "RoleId", commandType: CommandType.StoredProcedure);
                userInfo = users.FirstOrDefault();
            });
            if (userInfo == null)
            {
                return Error(QDCommon.Model.StateCode.UserNotExist, "user not exist or password error");
            }
            else
            {
              
                return Succed(userInfo);
            }
        }
    }
}
